# 导入第三方包
import pandas as pd
import numpy as np
import seaborn as sns
# 导入k近邻模型的类
from sklearn.neighbors import KNeighborsClassifier

# 数据读取
income = pd.read_excel(r'F:\\python_Data_analysis_and_mining\\02\\income.xlsx')
# 查看数据集是否存在缺失值
a = income.apply(lambda x:np.sum(x.isnull()))

# 缺失值处理
income.fillna(value = {'workclass':income.workclass.mode()[0],
'occupation':income.occupation.mode()[0],
'native-country':income['native-country'].mode()[0]}, inplace = True)

# 离散变量的重编码
for feature in income.columns:
    if income[feature].dtype == 'object':
        income[feature] = pd.Categorical(income[feature]).codes
print(income.head())

# 数据拆分
from sklearn.cross_validation import train_test_split

X_train, X_test, y_train, y_test = train_test_split(income.loc[:,'age':'native-country'],
income['income'], train_size = 0.75,
random_state = 1234)

# print(X_train)
print('训练数据集共有%d条观测' %X_train.shape[0])
print('测试数据集共有%d条观测' %X_test.shape[0])

# K近邻模型的网格搜索法
# 导入网格搜索法的函数
from sklearn.grid_search import GridSearchCV
import matplotlib.pyplot as plt

# 选择不同的参数
k_options = list(range(1,12))
parameters = {'n_neighbors':k_options}

# 搜索不同的K值
grid_kn = GridSearchCV(estimator = KNeighborsClassifier(), param_grid = parameters, cv=10, scoring='accuracy', verbose=0)
grid_kn.fit(X_train, y_train)
print(grid_kn)
# 结果输出
print(grid_kn.grid_scores_, grid_kn.best_params_, grid_kn.best_score_)
# 预测测试集
grid_kn_pred = grid_kn.predict(X_test)
print(pd.crosstab(grid_kn_pred, y_test))

# 模型得分
print('模型在训练集上的准确率%f' %grid_kn.score(X_train,y_train))
print('模型在测试集上的准确率%f' %grid_kn.score(X_test,y_test))

# 导入模型评估模块
from sklearn import metrics
# 绘制ROC曲线
fpr, tpr, _ = metrics.roc_curve(y_test, grid_kn.predict_proba(X_test)[:,1])
plt.plot(fpr, tpr, linestyle = 'solid', color = 'red')
plt.stackplot(fpr, tpr, color = 'steelblue')
plt.plot([0,1],[0,1], linestyle = 'dashed', color = 'black')
plt.text(0.6,0.4,'AUC=%.3f' % metrics.auc(fpr,tpr), fontdict = dict(size = 18))
plt.show()